/**
 * @class Controller for the general utility methods
 */
UtilC = new function(){
  /**
  * Close the feedback message box.
  * @returns void
  */
  this.closeFeedback = function() {
  	$('.feedback').slideUp('fast');
  }

  this.urlencode = function( str ) {
        var histogram = {}, tmp_arr = [];
        if(typeof(str) == 'string') {
            var ret =  str.toString();
        }
        else {
            var ret = str;
        }

        var replacer = function(search, replace, str) {
            var tmp_arr = [];
            tmp_arr = str.split(search);
            return tmp_arr.join(replace);
        };

        // The histogram is identical to the one in urldecode.
        histogram["'"]   = '%27';
        histogram['(']   = '%28';
        histogram[')']   = '%29';
        histogram['*']   = '%2A';
        histogram['~']   = '%7E';
        histogram['!']   = '%21';
        histogram['%20'] = '+';

        // Begin with encodeURIComponent, which most resembles PHP's encoding functions
        ret = encodeURIComponent(ret);

        for (search in histogram) {
            replace = histogram[search];
            ret = replacer(search, replace, ret) // Custom replace. No regexing
        }

        // Uppercase for full PHP compatibility
        return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
            return "%"+m2.toUpperCase();
        });

        return ret;
  }

  /**
  * Clear all the error messages on the field�s labels.
  * @returns void
  */
  this.clearFormErrors = function() {
  	$(".error").remove();
  }

  /**
   * Clear form error and close the feedback box message
   * @returns void
   */
  this.clearFormErrorsAndCloseFeedback = function() {
    UtilC.closeFeedback();
    UtilC.clearFormErrors();
    return true;
  }

  /**
  * Show the feedback message box with the specified message.
  * @param params The feedback
  * @param params.message The feedback message
  * @param params.fieldName The field name to apply the feedback message
  * @returns void
  */
  this.showFeedback = function(params) {
      //$('#feedback').html(params.message);
      $.jGrowl(params.message);
  }

  this.showBigFeedback = function(params) {
      //$('#feedback').html(params.message);
      UtilC.displayDialog({data:params.message});
  }

  /**
   * Change the page contents for the received html data.
   * @param params.data The html to show.
   */
  this.displayPageContents = function(params) {
    $('#page-contents').html(params.data);
  }

  this.displayDialog = function(params) {
    $(document.body).append("<div id='UtilC-dialog'></div>");
    $('#UtilC-dialog').html(params.data);
    delete(params.data);
    params.beforeclose = function() {
      $('#UtilC-dialog').remove();
    }
    $('#UtilC-dialog').dialog(params);
  }

  this.closeDialog = function() {
    $('#UtilC-dialog').remove();
  }


  this.showDebugMessage = function(message) {
    UtilC.showFeedback({"message":message});
  }

  this.showExceptionFeedback = function(params) {
  	UtilC.showFeedback(params);
  	$('.feedback').addClass('exception');
  }

  /**
   * Call the ajax stub test
   *
   * @param {String} phpController The php controller
   * @param {String} testName The test name to be executed
   */
  this.callAjaxStubTest = function(phpController,testName) {
  	$.getJSON(base_url + phpController + '/ajaxStubTests/testName/' + testName, null, JsonC.receiveJsonCall );
  }

  /**
   * Show the form error message
   *
   * @param params  The error
   * @param params.message The error message
   * @param params.fieldName The field name to apply the error message
   * @returns void
   */
  this.showFormError = function(params) {
  	$("label[for='" + params.fieldName + "']").append(
  	  '<em class="error">'+params.message+'</em>'
  	);
  }

  /**
   * Show form global error
   *
   * @param params The global error
   * @param params.message The global error message
   * @param params.formName The form name to apply the message
   * @returns void
   */
  this.showFormGlobalError = function(params) {
  	$("#"+params.formName).prepend(
  	  '<em class="error">'+params.message+'</em>'
  	);
  }

  /**
   * Submit a form with ajax json
   *
   * @param {String} formId The form element id
   * @returns void
   */
  this.submitAjaxJsonForm = function(formId) {
    alert('deprecated, use the JsonC.submitForSfAction');
    $('#'+formId).ajaxForm({
      dataType: 'json',
      success: JsonC.receiveJsonCall,
      error: JsonC.receiveJsonCallError
    });

    UtilC.x = $('#'+formId);
    $('#'+formId).submit();
  }

  this.sfRedirect = function(json) {
    var path = json.path;
    var parameters = json.parameters || {};
    document.location = JsonC.genSfUrl(path,parameters);
  }

  this.getAttrUpTheTree = function(item,attrName) {
    if(
      $(item).attr(attrName) != undefined &&
      ( typeof $(item).attr(attrName) === 'string' )
    ) {
      return $(item).attr(attrName);
    }
    else {
      parentNode = $(item).parent()[0];
      if(parentNode != undefined) {
        return RouterC.getAttrUpTheTree($(item).parent()[0],attrName);
      }
      else return null;
    }
  }

  this.sleep = function(milliseconds) {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++) {
      if ((new Date().getTime() - start) > milliseconds){
        break;
      }
    }
  }

  /**
   * As esceptions que n�o tem como ser tratadas e devem ser mostradas para o usu�rio devem
   * ser encaminhadas para este m�todo para que se possa mostra-las apenas no ambiente de desenv.
   */
  this.handleException = function(e) {
    UtilC.showExceptionFeedback({message:"Uncaught Javascript Exception("+e.name+'), message:'+e.message});
  }
}